#pragma once
/**
 * 抽象页面类，一个页面表示一屏界面。页面类定义了页面的状态和一些控制操作，主要起到MVC模式中C的作用
 */
#include "AppAnim.h"

typedef enum
{
	IDLE = 0,        // 空闲状态
	LOAD,            // 加载状态-准备阶段，还没有页面，此刻可以创建页面结构，添加事件，数据模块初始化等
	WILL_SHOW,       // 准备显示状态-页面将要出现，转场动画执行阶段
	SHOW,            // 显示状态-转场动画结束，页面显示完成
	ACTIVITY,        // 激活状态-页面处于运行显示阶段
	WILL_CLOSE,      // 准备关闭状态-页面将要消失，转场动画执行阶段
	CLOSE,           // 关闭状态-转场动画结束，页面关闭完成
	UNLOAD,          // 页面卸载完成
	UNKOWN
} page_state_em;

 /* 页面数据 */
typedef struct
{
	void* buf;
	uint32_t size;

} page_data_t;

class AppRouter;

class IPage {

public:
	IPage() { Init(); }
	virtual ~IPage() {}

	/* 【页面加载】，此时可以执行UI创建和数据初始化等 */
	virtual void OnViewLoad() {}

	/* 【页面展示】，转场动画完成, 页面完成显示 */
	virtual void OnViewShow() {}

	/* 【页面关闭】，页面消失前的响应*/
	virtual void OnViewEnd() {}

	/* 【页面卸载】，转场动画完成 */
	virtual void OnViewUnload() {}

	// 定时器响应, 返回true会继续执行timer
	virtual bool OnTimer() { return false; }

	// 屏幕滑动事件响应
	virtual void OnScrSlideUp() {};
	virtual void OnScrSlideDown() {};
	virtual void OnScrSlideLeft() {};
	virtual void OnScrSlideRight() {};
		
	// 其他事件
	virtual void OnEvent(lv_event_code_t code, lv_obj_t* obj) {};

	// 增加实际响应
	void AddEvent(lv_obj_t* obj)
	{
		lv_obj_add_event_cb(obj, HandleEvent, LV_EVENT_ALL, this);
	}

	// 是否开启缓存
	void EnableCache(bool bEnable) { m_bReqCache = bEnable; };

	// 设置加载动画属性
	void SetLoadAnim(anim_type_em type, uint16_t time = 200, lv_anim_path_cb_t path = lv_anim_path_linear);

	// 弹出页面的数据
	bool PopPageData(void* ptr, uint32_t size);

	// 导航（不缓存）
	bool GoTo(const char* name, anim_type_em type = anim_type_em::LOAD_ANIM_NONE, const page_data_t* param = nullptr);

	// 导航（缓存）
	bool GoNext(const char* name, anim_type_em type = anim_type_em::LOAD_ANIM_NONE, const page_data_t* param = nullptr);

	// 返回
	bool GoBack(const char* name, anim_type_em type = anim_type_em::LOAD_ANIM_NONE, const page_data_t* param = nullptr);

	// 主页
	bool GoHome();

	/*
	   @brief  设置定时器
	   @param  time: 时间间隔(微秒ms)；repeat: 重复次数
	*/
	void SetTimer(uint32_t time);

private:
	friend AppRouter;
	// 屏幕事件
	void AddScreenEvent() { 
		lv_obj_add_event_cb(lv_scr_act(), HandleEvent, LV_EVENT_GESTURE, this); 
	}
	void ClearScreenEvent() { 
		lv_obj_remove_event_cb(lv_scr_act(), HandleEvent); 
	}

public:
	lv_obj_t* m_body;        // 屏幕（根节点）
	const char* m_name;      // 页面名
	bool m_bReqCache;        // 请求缓存
	bool m_bCached;          // 是否已缓存

	page_data_t m_data;         // 页面数据
	page_state_em m_state;      // 页面状态
	anim_state_t m_anim;        // 页面动画

private:
	lv_timer_t* m_timer;

	static void HandleTimer(lv_timer_t* timer);

	// 处理事件
	static void HandleEvent(lv_event_t* event);

	// 初始化
	void Init(const char* name = nullptr);
};
